package org.rowan.infovis.soccer;

import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureCoords;
import com.sun.opengl.util.texture.TextureIO;
import java.io.File;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;

public class FieldViewer {

    public final float FIELD_HEIGHT = 500f;
    public final float FIELD_WIDTH = 750f;
    public final float FIELD_X = 125f;
    public final float FIELD_Y = 150f;
    private boolean textureLoaded = false;
    private Texture turf;
    private Texture ball;

    private float playerMenuStartX;
    private float playerMenuStartY;
    private float navStartX;
    private float navStartY;

    CategoryNav category;
    private PlayerMenu playerMenu;
    
    private GL gl;
    private GLAutoDrawable drawable;
    private TeamManager teamManager;
    private StateManager state;

    public FieldViewer(TeamManager tm, StateManager s) {
        category = new CategoryNav();
        this.teamManager = tm;
        this.state = s;
        this.playerMenu = new PlayerMenu(tm,state);

    }

    public void draw(GL gl, GLAutoDrawable drawable) {
        this.gl = gl;
        this.drawable = drawable;

        if (!textureLoaded) {
            ball = loadTexture("src/org/rowan/infovis/soccer/soccer.png");
            turf = loadTexture("src/org/rowan/infovis/soccer/turf.png");
            textureLoaded = true;
        }

        drawField(gl);

        if (state.fileImported()) {
            // draw player menu
            gl.glPushMatrix();
            playerMenuStartX = FIELD_X + 10;
            playerMenuStartY = FIELD_Y - 25;
            gl.glTranslated(playerMenuStartX, playerMenuStartY, 0);
            playerMenu.draw(gl, playerMenuStartX, playerMenuStartY);
            gl.glPopMatrix();
        }

        gl.glColor3f(1f, 1f, 1f);

        gl.glBegin(GL.GL_LINES);
        gl.glVertex2d(FIELD_X + FIELD_WIDTH / 2, FIELD_Y);
        gl.glVertex2d(FIELD_X + FIELD_WIDTH / 2, FIELD_Y + FIELD_HEIGHT);
        gl.glEnd();

        gl.glPushMatrix();
        Goal leftGoal = new Goal(true, teamManager.getCurrentTeam().getCurrentPlayer().getPrecisionData(category.getMode()));
        gl.glTranslated(FIELD_X - leftGoal.getWidth() - 5f, FIELD_Y + (FIELD_HEIGHT / 2) - (leftGoal.getHeight() / 2), 0);
        leftGoal.draw(gl, drawable, this);
        gl.glPopMatrix();

        gl.glPushMatrix();
        navStartX = FIELD_X + FIELD_WIDTH + 3;
        navStartY = FIELD_Y + (FIELD_HEIGHT / 2) - (category.getHeight() / 2);
        gl.glTranslated(navStartX, navStartY, 0);
        category.draw(gl, navStartX, navStartY);
        gl.glPopMatrix();

        gl.glPushMatrix();
        MechanicsPlot plot = new MechanicsPlot(teamManager.getCurrentTeam().getCurrentPlayer().getFluencyData(category.getMode()),
                teamManager.getCurrentTeam().getCurrentPlayer().getCoordinationData(category.getMode()),
                teamManager.getCurrentTeam().getCurrentPlayer().getEasinessData(category.getMode()),
                teamManager.getCurrentTeam().getCurrentPlayer().getRapidityData(category.getMode()));

        gl.glTranslated(FIELD_X + FIELD_WIDTH / 2, FIELD_Y + (FIELD_HEIGHT / 2), 0);
        plot.draw(gl);
        gl.glPopMatrix();

        //144 is the highest value before resizing will be needed (if added)
        gl.glPushMatrix();
        TacticalUtility tu = new TacticalUtility(ball, teamManager.getCurrentTeam().getCurrentPlayer().getTacticalUtilityData(category.getMode()));
        gl.glTranslated(FIELD_X + FIELD_WIDTH / 2 + FIELD_WIDTH / 5, FIELD_Y + FIELD_HEIGHT - FIELD_HEIGHT / 8, 0);
        tu.draw(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glTranslated(FIELD_X + 65, FIELD_Y + 50, 0);
        Movement m = new Movement(teamManager.getCurrentTeam().getCurrentPlayer().getSlowExecutionData(category.getMode()), drawable, this);
        m.draw(gl);
        gl.glPopMatrix();

        gl.glPushMatrix();
        gl.glTranslated(FIELD_X + 15, FIELD_Y + FIELD_HEIGHT / 3, 0);
        gl.glScaled(0.25, 0.25, 0.25);
        Mistakes mistake = new Mistakes(teamManager.getCurrentTeam().getCurrentPlayer().getTorsoMistakesData(category.getMode()),
                                        teamManager.getCurrentTeam().getCurrentPlayer().getFootMistakesData(category.getMode()));
        mistake.draw(gl);
        gl.glPopMatrix();

        gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
    }

    private Texture loadTexture(String filename) {
        Texture texture = null;
        try {
            texture = TextureIO.newTexture(new File(filename), false);
            texture.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
            texture.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
        } catch (Exception e) {
            System.out.println("error loading texture from " + filename);
        }

        return texture;
    }

    private void drawField(GL gl) {
        gl.glColor3f(1f, 1f, 1f);

        //border - scale instead?
        gl.glPushMatrix();
        gl.glBegin(GL.GL_QUADS);
        gl.glVertex2f(FIELD_X - 3f, FIELD_Y - 3f);
        gl.glVertex2f(FIELD_X - 3f, FIELD_Y + FIELD_HEIGHT + 3f);
        gl.glVertex2f(FIELD_X + FIELD_WIDTH + 3f, FIELD_Y + FIELD_HEIGHT + 3f);
        gl.glVertex2f(FIELD_X + FIELD_WIDTH + 3f, FIELD_Y - 3f);
        gl.glEnd();
        gl.glPopMatrix();

        TextureCoords tc = turf.getImageTexCoords();
        float tx1 = tc.left();
        float ty1 = tc.bottom();
        float tx2 = tc.right();
        float ty2 = tc.top();

        turf.enable();
        turf.bind();

        gl.glPushMatrix();
        gl.glBegin(GL.GL_QUADS);
        gl.glTexCoord2f(tx1, ty1);
        gl.glVertex2f(FIELD_X, FIELD_Y);
        gl.glTexCoord2f(tx1, ty2);
        gl.glVertex2f(FIELD_X, FIELD_Y + FIELD_HEIGHT);
        gl.glTexCoord2f(tx2, ty2);
        gl.glVertex2f(FIELD_X + FIELD_WIDTH, FIELD_Y + FIELD_HEIGHT);
        gl.glTexCoord2f(tx2, ty1);
        gl.glVertex2f(FIELD_X + FIELD_WIDTH, FIELD_Y);
        gl.glEnd();
        gl.glPopMatrix();

        turf.disable();
    }

    public void mouseReleased(int x, int y) {
        category.mouseReleased(x, y);
        playerMenu.mouseReleased(x, y);
    }

    public void mouseMoved(int x, int y) {
        category.mouseMoved(x, y);
        playerMenu.mouseMoved(x, y);
    }
}
